package com.csj.mvvmtest.util;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
 * 公共目录DCIM的文件读写（数据存取）
 * PS:不通过 startActivityForResult(intent, ALL_FILES_ACCESS_PERMISSION)来获取全部文件访问
 * PS:android 11 强制启用Scoped Storage
 */

public class UUIDUtils {

    private static final String TAG = UUIDUtils.class.getName();
    private static UUIDUtils device;
    private static Context context;
    private final static String SP_DEFAULT_NAME = "sp_device_id";
    private final static String DEFAULT_FILE_NAME = "system_device_id";
    private final static String DEFAULT_DEVICE_ID = "device_id";
    private final static String FILE_ANDROID = Environment.getExternalStoragePublicDirectory("Download") + File.separator + DEFAULT_FILE_NAME;
    private final static String FILE_DCIM = Environment.getExternalStoragePublicDirectory("DCIM") + File.separator + DEFAULT_FILE_NAME;
    private static SharedPreferences preferences = null;
    private static CheckPermission checkPermission;

    public interface CheckPermission {
        void ok();

    }

    public UUIDUtils(Context context) {
        UUIDUtils.context = context;
    }

    private String uuid;

    public static String getUUID() {
        if (preferences == null) {
            Log.d(TAG, "Please check the UUIDS.buidleID in Application (this).Check ()");
            return DEFAULT_DEVICE_ID;
        }
        return preferences.getString(DEFAULT_DEVICE_ID, DEFAULT_DEVICE_ID);
    }

    public static UUIDUtils buidleID(Context context) {
        if (device == null) {
            synchronized (UUIDUtils.class) {
                if (device == null) {
                    device = new UUIDUtils(context);
                }
            }
        }
        return device;
    }

    //生成一个128位的唯一标识符
    private String createUUID() {
        return UUID.randomUUID().toString();
    }


    public void check() {
//        if (NDRxPermitionUtil.isPermission()) {
//            if (NDRxPermitionUtil.getInstance((Activity) context).isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//                checkStep();
//                return;
//            }
//            NDRxPermitionUtil.getInstance((Activity) context).request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(new Action1<Boolean>() {
//                @Override
//                public void call(Boolean aBoolean) {
//                    if (aBoolean) {
//                        checkStep();
//                    } else {
//                        NDRxPermitionUtil.getInstance((Activity) context).shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(new Action1<Boolean>() {
//                            @Override
//                            public void call(Boolean aBoolean) {
//                                NdPermissions.sCancel = "Cancel";
//                                NdPermissions.sOk = "OK";
//                                NdPermissions.sTip = "";
//                                NdPermissions.sSetting = "Setting";
//                                NdPermissions.TODO.openPermissionsDialog((Activity) context, context.getString(R.string.nd_permission_phone_set), !aBoolean, NdPermissions.REQUEST_CODE.LOGIN, null);
//
//                            }
//                        });
//                    }
//                }
//            });
//        } else {
//            checkStep();
//        }
        checkStep();
    }


    private void checkStep() {
        preferences = context.getSharedPreferences(SP_DEFAULT_NAME, 0);
        uuid = preferences.getString(DEFAULT_DEVICE_ID, null);
        if (uuid == null) {
            uuid = checkAndroidFile();
            if (TextUtils.isEmpty(uuid)) {
                uuid = createUUID();
//                saveAndroidFile(uuid);
                writeToFile(uuid);
            }
            SharedPreferences.Editor editor = preferences.edit();
            editor.putString(DEFAULT_DEVICE_ID, uuid);
            editor.apply();
            Log.d(TAG, "save SharePref:" + uuid);
        } else {
            if (TextUtils.isEmpty(checkAndroidFile())) {
//                saveAndroidFile(uuid);
                writeToFile(uuid);
            }
        }
        Log.d(TAG, "result uuid:" + uuid);
        checkPermission.ok();
    }

    private String checkAndroidFile() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
            BufferedReader bufferedReader = null;
            StringBuilder stringBuilder = new StringBuilder();
            try {
                InputStream fis = getImageIns();
                if (fis == null) {
                    return "";
                }
//            FileInputStream fis = context.openFileInput(DEFAULT_FILE_NAME);//保存到私有目录
                InputStreamReader inputStreamReader = new InputStreamReader(fis, StandardCharsets.UTF_8);
                bufferedReader = new BufferedReader(inputStreamReader);
                String line = null;
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bufferedReader != null) {
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            Log.d(TAG, "checkAndroidFile=" + stringBuilder.toString());
            return stringBuilder.toString();
        } else {
            BufferedReader reader = null;
            try {
                File file = new File(FILE_DCIM);
                Log.d(TAG, "checkAndroidFile:" + file.toString());
                reader = new BufferedReader(new FileReader(file));
                return reader.readLine();
            } catch (Exception e) {
                return "";
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public InputStream getImageIns() {
        InputStream ins = null;
        ContentResolver resolver = context.getContentResolver();
        String sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " DESC";//根据日期降序查询
        String selection = MediaStore.Images.Media.DISPLAY_NAME + " like '" + DEFAULT_FILE_NAME + ".jpg'";
        Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, selection, null, sortOrder);
        try {
            if (cursor != null && cursor.moveToFirst()) {
                //媒体数据库中查询到的文件id
                int columnId = cursor.getColumnIndex(MediaStore.Images.Media._ID);
                Log.d(TAG, "read columnId=" + columnId);
                do {
                    //通过mediaId获取它的uri
                    int mediaId = cursor.getInt(columnId);
                    Uri itemUri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + mediaId);
                    try {
                        //通过uri获取到inputStream
                        ContentResolver cr = context.getContentResolver();
                        ins = cr.openInputStream(itemUri);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } while (cursor.moveToNext());
                cursor.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ins;

    }

    public void writeToFile(String id) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
            try {
                ContentValues values = new ContentValues();
                values.put(MediaStore.MediaColumns.DISPLAY_NAME, DEFAULT_FILE_NAME);
                values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);
                } else {
                    String galleryPath = Environment.getExternalStorageDirectory()
                            + File.separator + Environment.DIRECTORY_DCIM + File.separator;
                    values.put(MediaStore.MediaColumns.DATA, galleryPath + DEFAULT_FILE_NAME);
                }
                ContentResolver contentResolver = context.getContentResolver();
                Uri uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                if (uri != null) {
                    OutputStream os = contentResolver.openOutputStream(uri, "wt");
                    if (os != null) {
                        os.write(id.getBytes());
                        os.flush();
                        os.close();
                    }
                }
                Log.d(TAG, "write uuid");
            } catch (Exception e) {
            }
        } else {
            try {
                File file = new File(FILE_DCIM);
                FileWriter writer = new FileWriter(file);
                writer.write(id);
                writer.flush();
                writer.close();
                Log.d(TAG, "write uuid");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
//        try {
//            ContentResolver resolver = context.getContentResolver();
//            ContentValues values = new ContentValues();
//            values.put(MediaStore.MediaColumns.DISPLAY_NAME, DEFAULT_FILE_NAME);
//            values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain");
//            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);
//            Uri uri = resolver.insert(MediaStore.Files.getContentUri("external"), values);
//            OutputStream os = resolver.openOutputStream(uri, "wt");
//            if (os != null) {
//                os.write(id.getBytes());
//                os.flush();
//                os.close();
//            }
//            Log.d(TAG, "write uuid");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }


    private void saveAndroidFile(String id) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
            try {
                ContentResolver resolver = context.getContentResolver();
                ContentValues values = new ContentValues();
                values.put(MediaStore.Files.FileColumns.DISPLAY_NAME, DEFAULT_FILE_NAME);
                values.put(MediaStore.Files.FileColumns.MIME_TYPE, "text/plain");
                values.put(MediaStore.Files.FileColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS);
                Uri uri = resolver.insert(MediaStore.Files.getContentUri("external"), values);
                OutputStream os = resolver.openOutputStream(uri, "wt");
                if (os != null) {
                    os.write(id.getBytes());
                    os.flush();
                    os.close();
                }
                Log.d(TAG, "write uuid");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                File file = new File(FILE_DCIM);
                FileWriter writer = new FileWriter(file);
                writer.write(id);
                writer.flush();
                writer.close();
                Log.d(TAG, "write uuid");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //保存到私有目录
//        BufferedWriter bufferedWriter = null;
//        try {
//            FileOutputStream fileOutputStream = context.openFileOutput(DEFAULT_FILE_NAME, Context.MODE_PRIVATE);
//            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
//            bufferedWriter.write(id);
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            if (bufferedWriter != null) {
//                try {
//                    bufferedWriter.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
    }

    /**
     * 弃用
     * 保存为文件类型的，不是本应用创建的无法读取
     *
     * @return
     */
    public InputStream getImageIns2() {
        InputStream ins = null;
        ContentResolver resolver = context.getContentResolver();
//        String sortOrder = MediaStore.Files.FileColumns.DATE_MODIFIED + " DESC";//根据日期降序查询
//        String selection = MediaStore.Files.FileColumns.DISPLAY_NAME + " like '" + DEFAULT_FILE_NAME + ".txt'";   //查询条件 “显示名称为？”
//        Cursor cursor = resolver.query(MediaStore.Files.getContentUri("external"), null, selection, null, sortOrder);
        // 需要查询的资源
        Uri uri = MediaStore.Files.getContentUri("external");
// 需要查询的字段，根据display_name模糊查询，size大于0的，date_modified倒序
        String[] columns = {
                MediaStore.Files.FileColumns.DISPLAY_NAME,
                MediaStore.Files.FileColumns.SIZE,
                MediaStore.Files.FileColumns.DATE_MODIFIED
        };
// where条件
        String where = "(_display_name like '%.png' or _display_name like '%.jpg') and _size > 0";
//        String where = "(_display_name like '%.txt') and _size > 0";
// 组装查询
        Bundle select = new Bundle();
// 偏移量，也就是从第几条开始查询 page是页码，limit是每页数量，根据逻辑自行修改
//        int start = (page - 1) * limit;
//        select.putInt(ContentResolver.QUERY_ARG_LIMIT, limit);
//        select.putInt(ContentResolver.QUERY_ARG_OFFSET, start);
// 排序方向，倒序
        select.putInt(ContentResolver.QUERY_ARG_SORT_DIRECTION, ContentResolver.QUERY_SORT_DIRECTION_DESCENDING);
        select.putStringArray(ContentResolver.QUERY_ARG_SORT_COLUMNS, new String[]{MediaStore.Files.FileColumns.DATE_MODIFIED});
// where条件
        select.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, where);
// 这个query方法参数是4个
        Cursor cursor = resolver.query(uri, columns, select, null);

        if (cursor != null) {
            if (cursor.moveToFirst()) {
                //媒体数据库中查询到的文件id
                int columnId = cursor.getColumnIndex(MediaStore.Files.FileColumns._ID);
                Log.d(TAG, "read columnId=" + columnId);
                do {
                    if (columnId < 0) {
                        break;
                    }
                    //通过mediaId获取它的uri
                    int mediaId = cursor.getInt(columnId);
                    Uri itemUri = Uri.withAppendedPath(MediaStore.Files.getContentUri("external"), "" + mediaId);
                    try {
                        //通过uri获取到inputStream
                        ContentResolver cr = context.getContentResolver();
                        ins = cr.openInputStream(itemUri);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } while (cursor.moveToNext());
            }
            try {
                cursor.close();
            } catch (Exception ignored) {
            }
        }
        return ins;
    }

    public static void setCheckPermissionListener(CheckPermission c) {
        checkPermission = c;
    }

    public static void setContext(Context mContext) {
        context = mContext;
    }
}
